package com.threegroup.admin.service;



import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.threegroup.common.dao.DishDao;
import com.threegroup.common.dao.OrderDetailDao;
import com.threegroup.common.dao.OrdersDao;
import com.threegroup.common.dto.OrderDetailDTO;
import com.threegroup.common.dto.OrderDetailPageDTO;
import com.threegroup.common.entity.DishEntity;
import com.threegroup.common.entity.OrderDetailEntity;
import com.threegroup.common.utils.Result;
import com.threegroup.common.validator.AssertUtils;
import com.threegroup.common.vo.OrderDetailInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.threegroup.admin.utils.AssertUtil;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
public class OrderDetailService {
    //订单明细
    @Resource
    private OrderDetailDao orderDetailDao;
    //订单
    @Resource
    private OrdersDao ordersDao;
    //菜品
    @Resource
    private DishDao dishDao;

    //添加订单明细
    @Transactional(propagation = Propagation.REQUIRED)
    public Result addOrderDetail(OrderDetailDTO orderDetailDTO,Long orderId){

        /**
         * 校验orderId是否存在
         *      存在表明是添加用户订单时添加的订单明细
         *          设置orderId值
         *      不存在表示单独添加的订单明细，orderId是前端orderDetailDTO里传来的
         *          校验orderId值
         *              1.不能为空
         *              2.数据库中存在
         */
        if (null==orderId){
            orderId = orderDetailDTO.getOrderId();
            AssertUtils.isNull(orderId,302);
            AssertUtil.isTrue(ordersDao.selectByPrimaryKey(orderId)==null,"该订单不存在");
        }

        //1.参数校验

        Result result = new Result();
        AssertUtils.isNull(orderDetailDTO,302,"订单详情为空");

        //提取数据
        //BigDecimal amount = orderDetailDTO.getAmount();
        //String dishFlavor = orderDetailDTO.getDishFlavor();
        Long dishId = orderDetailDTO.getDishId();
        String image = orderDetailDTO.getImage();
        String name = orderDetailDTO.getName();
        Integer number = orderDetailDTO.getNumber();
        //Long setmealId = orderDetailDTO.getSetmealId();
        /*  菜品ID
            1.不能为空
            2.数据库中存在
         */
        AssertUtils.isNull(dishId,302);
        DishEntity dishTemp = dishDao.selectByPrimaryKey(dishId);
        AssertUtil.isTrue(dishTemp == null,"该菜品不存在");

        /*数量
            1.不能为空并且非负
         */
        AssertUtil.isTrue(null==number||number<=0,"数量有误");

        /*
        金额
            1.和菜品ID关联从数据库中查
            2.不能为空
            3.不能为0或为负数
         */
        BigDecimal amount = dishTemp.getPrice().multiply(BigDecimal.valueOf(number));
        AssertUtil.isTrue(null==amount||amount.compareTo(BigDecimal.ZERO)<=0,"订单详情金额有误");


        //设置默认值
        //设置订单明细名的默认值
        name = (dishTemp.getName());

        //插入数据到Entity数据模型
        OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
        orderDetailEntity.setOrderId(orderId);
        orderDetailEntity.setName(name);
        orderDetailEntity.setAmount(amount);
        orderDetailEntity.setNumber(number);
        orderDetailEntity.setDishId(dishId);
        orderDetailEntity.setImage(dishTemp.getImage());

        //执行插入操作
        AssertUtil.isTrue(orderDetailDao.insertSelective(orderDetailEntity)<1,"添加订单明细失败");

        return result;
    }

    //修改订单明细
    @Transactional(propagation = Propagation.REQUIRED)
    public Result updeteOrderDetail(OrderDetailDTO orderDetailDTO) {
        //1.参数校验
        Result result = new Result();
        AssertUtils.isNull(orderDetailDTO,302,"订单详情为空");

        //提取数据
        Long id = orderDetailDTO.getId();
        BigDecimal amount = orderDetailDTO.getAmount();
        //String dishFlavor = orderDetailDTO.getDishFlavor();
        Long dishId = orderDetailDTO.getDishId();
        String image = orderDetailDTO.getImage();
        String name = orderDetailDTO.getName();
        Integer number = orderDetailDTO.getNumber();
        Long orderId = orderDetailDTO.getOrderId();
        //Long setmealId = orderDetailDTO.getSetmealId();

        /*
        订单详情ID
            1.非空
            2.数据库中存在
         */
        AssertUtils.isNull(id,"订单详情ID不能为空");
        OrderDetailEntity orderDetailTemp = orderDetailDao.selectByPrimaryKey(id);
        AssertUtil.isTrue(null==orderDetailTemp,"订单详情ID不不存在");

        String dishName;
        /*
        菜品ID
          非空
                1.数据库中存在
                图片 设置修改菜品后默认的菜品图片
                    1.判断菜品是否修改
                    2.从修改的菜品Id中获取
                数量 设置修改菜品后默认的菜品数量
                    判断数量是否为空
                        空 设置默认数量为1
                        非空 设置设置该数量
                金额 设置修改菜品后默认的菜品金额
                        判断金额是否为空
                        1.设置默认金额为1分的价格
         */
        if (null!=dishId){
            DishEntity dishTemp = dishDao.selectByPrimaryKey(dishId);
            AssertUtil.isTrue(dishTemp == null,"该菜品不存在");
            image = dishTemp.getImage();
            dishName= dishTemp.getName();
            if (null==number){
                number=1;
            }
            if (null==amount){
                amount = dishTemp.getPrice().multiply(BigDecimal.valueOf(number));
            }
            AssertUtil.isTrue(amount.compareTo(BigDecimal.ZERO)<=0,"订单详情金额有误");
        }else {
            /*
            菜品ID为空（原来的菜品）
              数量
                1.非空 非负
                2.空   默认为1
              金额
                1.非空 非负
                2.空   设置默认的number数量的菜品的总额
              图片 原来的菜品图片
            */
            DishEntity dishTemp = dishDao.selectByPrimaryKey(orderDetailTemp.getDishId());
            if (null==number){
                number=1;
            }
            AssertUtil.isTrue(number<=0,"数量有误");

            if (null==amount){
                amount = dishTemp.getPrice().multiply(BigDecimal.valueOf(number));
            }
            AssertUtil.isTrue(amount.compareTo(BigDecimal.ZERO)<=0,"订单详情金额有误");

            image = dishTemp.getImage();

            dishName= dishTemp.getName();
        }

        /*
        订单ID
            1.数据库中存在
         */
        if (null==orderId){
            orderId = orderDetailTemp.getOrderId();
        }
        AssertUtil.isTrue(ordersDao.selectByPrimaryKey(orderId)==null,"该订单不存在");


        //设置默认值
        //设置订单明细名的默认值
        name = (dishName);

        OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
        orderDetailEntity.setId(id);
        orderDetailEntity.setOrderId(orderId);
        orderDetailEntity.setName(name);
        orderDetailEntity.setAmount(amount);
        orderDetailEntity.setNumber(number);
        orderDetailEntity.setDishId(dishId);
        orderDetailEntity.setImage(image);

        //执行插入操作
        AssertUtil.isTrue(orderDetailDao.updateByPrimaryKeySelective(orderDetailEntity)<1,"更新订单明细失败");

        return result;
    }

    //删除订单明细
    @Transactional(propagation = Propagation.REQUIRED)
    public Result deleteOrderDetail(Long[] ids) {

        Result result = new Result();
        //判断ids是否为空
        AssertUtils.isNull(ids,"ids为空");

        for (Long id : ids) {
        //判断该数据是否存在
         OrderDetailEntity orderDetailEntity = orderDetailDao.selectByPrimaryKey(id);
         AssertUtils.isNull(orderDetailEntity,"待删除记录不存在");
        //删除该记录
        AssertUtil.isTrue(orderDetailDao.deleteByPrimaryKey(id)<1,"删除订单明细失败");
        }
        return result;
    }

    //查询该订单明细的订单信息
    public Result selectOrderDetail(Integer id) {
        Result result = new Result();
        //判断ids是否为空
        AssertUtils.isNull(id,"id为空");
        //判断该数据是否存在
        OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
        AssertUtils.isNull(orderDetailEntity = orderDetailDao.selectByPrimaryKey(id.longValue()),"该订单明细记录不存在");

        result.setData(orderDetailEntity);

        return result;
    }

    //查询根据orderId查多个订单明细信息
    public Result selectOrderDetailInfoVo(Long orderId) {

        Result result = new Result();
        //判断ids是否为空
        AssertUtils.isNull(orderId,"OrderId为空");
        //判断该数据是否存在

        List<OrderDetailEntity> orderDetailEntities = orderDetailDao.selectByOrderId(orderId);
        AssertUtils.isNull(orderDetailEntities,"该订单明细记录不存在");

        //新建一个orderDetailInfoVos存放赋值的orderDetailInfoVo
        List<OrderDetailInfoVo> orderDetailInfoVos = new ArrayList<>();
        for (OrderDetailEntity orderDetailEntity : orderDetailEntities) {
            OrderDetailInfoVo orderDetailInfoVo = new OrderDetailInfoVo();
            orderDetailInfoVo.setAmount(orderDetailEntity.getAmount());
            orderDetailInfoVo.setName(orderDetailEntity.getName());
            orderDetailInfoVo.setNumber(orderDetailEntity.getNumber());
            orderDetailInfoVos.add(orderDetailInfoVo);
        }

        result.setData(orderDetailInfoVos);
        return result;
    }

    //分页查询订单明细列表
    public Result selectOrderDetailList(OrderDetailPageDTO orderDetailPageDTO) {

        Result result = new Result();

        String order = orderDetailPageDTO.getOrder();
        Integer page = orderDetailPageDTO.getPage();
        Integer limit = orderDetailPageDTO.getLimit();
        String orderField = orderDetailPageDTO.getOrderField();
        //订单Id
        Long orderId = orderDetailPageDTO.getId();

        // 只允许指定的排序字段和排序方式，防止SQL注入
        String[] orderByArr = {"amount","id","number"};
        String orderByStr = "";
        if (StringUtils.isNotEmpty(orderField) && Arrays.asList(orderByArr).contains(orderField.toLowerCase())) {
            orderByStr = String.format("%s %s", orderField.toLowerCase(), "asc".equalsIgnoreCase(order) ? "asc" : "desc");
        } else {
            // 默认排序
            orderByStr = "id asc";
        }

        PageHelper.startPage(page, limit, orderByStr);
        List<OrderDetailEntity> orderDetailEntities = orderDetailDao.selectAll(orderId);
        PageInfo<OrderDetailEntity> orderDetailEntitiesPageInfo = new PageInfo<>(orderDetailEntities);

        Map<String,Object> map = new HashMap<>();
        map.put("list",orderDetailEntitiesPageInfo.getList());
        int total = (int) orderDetailEntitiesPageInfo.getTotal();
        map.put("total",total);
        result.setData(map);

        return result;
    }
}
